 <style lang="scss">
[mode='xml'] {
  .plumb-layout__tools {
    display: none;
  }
}
.cus-layout-editor2 {
  .plumb-layout__item-action {
    display: flex;
    align-items: center;
    //> *:first-child {
    //  width: 150px;
    //}
  }
  .plumb-layout .header {
    > * {
      //display: flex;
      > *:first-child {
        display: none;
        //height: 0;
        > *:first-child {

          display: none;
        }
      }
    }
  }
}
.cus-layout-editor2-area {
  --plumb-con-width: 360px;
  .el-descriptions__label {
    font-weight: bold;
    margin-right: 0;
    font-size: 0;
  }
  td:first-child {
    .el-descriptions__label {
      word-break: break-all;
    }
    .el-descriptions__content {
      //font-weight: bold;
      word-break: break-all;
      display: block;
      width: 8em;
    }
  }
}
.plumb-layout__header-desc-title {
  display: none;
}
.plumb-layout__header-type {
  display: none;
}
.plumb-layout .item {
  min-height: 40px;
}
.plumb-layout__header-desc-edit-btn {
  position: absolute;
  right: 0;
  top: 0;
  display: none;
}
.plumb-layout__plus-btn {
  display: none;
}
.plumb-layout__item-input-key {
  display: none;
}
.plumb-layout__item-delete-btn {
  display: none;
}
.plumb-layout__item-action {
  flex: 1;
}
.plumb-layout__list-con {
  height: 650px;
}
.el-descriptions--medium:not(.is-bordered) .el-descriptions__cell {
  padding-bottom: 0;
}
</style>

<template>
  <div class="cus-layout-editor2">
    <template v-if="inited">
      <!--    {{widgetConfig.enums}}-->
<!--      <el-row type="flex" >-->
<!--        <el-button size="small" @click="openDialog">打开编辑</el-button>-->
<!--      </el-row>-->
<!--      <el-dialog-->
<!--          v-model="state.dialogVisible"-->
<!--          title="编辑" width="80vw"-->
<!--          :close-on-click-modal="false"-->
<!--          :append-to-body="true"-->
<!--          @closed="onClosed"-->


<!--      >-->
        <div :mode="widgetConfig.mode" @mouseleave="onClickOutside">
          <el-row class="a-space-mb-10">
<!--            <el-button type="primary" @click="save">保存</el-button>-->
<!--            <el-button type="primary"-->
<!--                       @click="exportFun">导出</el-button>-->
<!--            <el-button  type="primary"-->
<!--                         @click="importFun">导入</el-button>-->
          </el-row>
<!--          <div>-->
<!--            <EwXmlShower :value="getXMLDisplay(state.value)"></EwXmlShower>-->
<!--          </div>-->
          <ZLayoutEditor
              :ref="setLayoutRef"
              :controls="false"
              @ele-drag-change="onEleDragChange"
              :store-prefix="storePrefix"
              :cus-handle-dep="cusHandleDep"
              :auto-load="false"
              :before-insert="beforeInsert"
              @plumb-inited="onPlumbInited"
              :plumb-options="plumbOptions"
              @plumb_events="onPlumbEvents"
              @mode:update:all="onPlumbUpdate"
              @del-dep="onPlumbDelDep"
              @save-layout="onSaveLayout"
              :weapp="widgetConfig.weapp"
              :handle-list1="handleList1"
              default-panel-width="450px"
              class="cus-layout-editor2-area"
          >
            <template #plumb-layout__item-header-beforeend="scope">
<!--              {{scope.dep.marking}}-->
              <div>表格 {{scope.dep.data.tableName}}</div>
              <el-space>
                <div>主表</div>
                <el-switch  v-model="scope.dep.marking" active-value="1" inactive-value="0"></el-switch>
              </el-space>
            </template>
            <template #plumb-layout-item-action-beforeend="scope">
<!--              {{scope.item.props}}-->
              <el-descriptions title="">
                <el-descriptions-item v-for="(prop, propKey) in filterItemProps(scope.item.props)"
                                      label="">{{prop}}</el-descriptions-item>
              </el-descriptions>
            </template>
          </ZLayoutEditor>
        </div>
<!--      </el-dialog>-->
    </template>
  </div>
</template>

<script>
import {CustomRenderControlMixin, defineCustomRender} from "@/plugins/form-render/utils";
import ZLayoutEditor from "@/plugins/z-frame/components/ZLayoutEditor.vue";
import {onBeforeUnmount} from "vue";
import {clearPlumbLayoutStorage} from "@/plugins/PlumbLayout/mixin";
import EwXmlShower from "@/components/Ew/EwXmlShower.vue";
import {getXmlData, getMiniAppXmlData, getHtmlXmlData} from "@/views/about/components/PlumbLayout/xmlData";
import {reqTableParam, reqTables} from "@/hooks/api";

async function cachedArrOperate(key = '', fun = () => {} ) {
  let cachedKeys = await ZY_EXT.store.getItem(key)
  if (!Array.isArray(cachedKeys)) {
    cachedKeys = []
  }
  // cachedKeys.push(v)
  cachedKeys = await fun(cachedKeys);
  await ZY_EXT.store.setItem(key, cachedKeys)
}

const OPERATE_PREFIX = 'layout-store-prefix'

export default {
  name: 'CusLayoutEditor2',
  components: {EwXmlShower, ZLayoutEditor},
  mixins: [
    CustomRenderControlMixin
  ],
  setup(props, ctx) {
    let {part_key} = props.defs;
    let obj;
    let JSON5 = ZY.JSON5;
    let storePrefix = ZY.rid(6);

    (async function () {
      await cachedArrOperate(OPERATE_PREFIX, (arr) => {

        arr.forEach(cachedKey => {
          clearPlumbLayoutStorage(cachedKey)
        })

        return []
      })
    })();

    let { data, methods, listeners, init, widgetConfig2 } = defineCustomRender(props, ctx, {
      handleValueInit(newVal) {
        if (!newVal) {
          newVal = '{data: {links: [], deps: []}, posMap: {}}'
        }
        if (newVal) {
          obj = JSON5.parse(newVal)
        }
        // openDialog()
        // console.log(obj)
        return newVal
      }
    })
    let state = data({
      dialogVisible: false,
      previewVisible: false
    })
    init(props)

    async function openDialog() {
      // state.dialogVisible =true

      await cachedArrOperate(OPERATE_PREFIX, (arr) => {
        return arr.concat([storePrefix])
      })
    }

    let cachedPlumbContext = null
    async function importData(context, obj) {
      console.log(obj.data)
      await context.importToolsData(obj)
      await ZY.sleep(300)
      context.LayoutContext.insComLinks(obj.realtions)
      await ZY.sleep(300)
      await context.saveCache2Storage(obj)
    }

    async function beforeInsert(element) {
      // console.log('beforeInsert', obj, element)
      let tableParams = await reqTableParam(element.name, {})
      // console.log('beforeInsert', element, tableParams)
      let items = tableParams.map(v => {
        return {
          fieldId: v.field,
          props: v
        }
      })
      element.data.v2 = true
      element.data.tableName = element.name
      element.items= items
      return element
    }

    async function onPlumbInited({context, LayoutContext}) {
      // console.log('CusLayoutEditor2 Init', obj, context)
      importData(context, obj)
      cachedPlumbContext = context
      let tableList = await reqTables({})
      let tableTags = tableList.map(tableName => {
        return {
          name: tableName,
          value: '',
          id: tableName,
          data: {
            tagName: 'div'
          },
          lib: '',
          items: [
          ]
        }
      })
      // console.log(LayoutContext)
      LayoutContext.list1 = LayoutContext.list1.concat(tableTags)
      await ZY.sleep(200)
      await openDialog()
    }

    function getValue(ctx) {
      let deps = ctx.deps
      let realtions = ctx.getLinkRealtions()
      // console.log(realtions)
      let links = realtions.map(link => {
        let mainDep = deps.find(dep => dep.id === link.fromPID)
        let childDep = deps.find(dep => dep.id === link.toPID)
        let mainField = mainDep.items.find(item => item.id === link.from)
        let childField = childDep.items.find(item => item.id === link.to)
        if (childField && childField.props) {
          let ret = {
            childTableName: childDep.data.tableName,
            childTableField: childField.props.field,
            childTableMarking: childDep.marking,
            mainTableName: mainDep.data.tableName,
            mainTableField: mainField.props.field,
            mainTableMarking: mainDep.marking,
            menuId: ''
          }
          // console.log(ret, link)
          return ret
        }
        return null
      }).filter(v => v)

      return  {
        links,
        realtions
      }
    }

    let layoutRef = null
    function setLayoutRef(target, options) {
      layoutRef = target
    }

    function onSaveLayout(e) {
      console.log('onSaveLayout', e)
    }

    function getXML() {
      let v = layoutRef.getXML()
      // console.log('getXML', v)
    }

    function onEleDragChange() {
      // console.log('onEleDragChange')
    }

    async function save() {
      let v = layoutRef.getToolsData()
      // console.log('getToolsData', v)
      await layoutRef.saveCache2Storage(v)


      let obj = getValue(layoutRef.LayoutContext)
       v = Object.assign(v, obj)
      // console.log(v)
      let ret = JSON5.stringify(v)
      methods.onChange(ret)
    }

    async function onClosed() {
      await save();
    }

    function getXMLDisplay(v) {
      return getApp().buildAllXml(v)
    }

    //filterItemProps
    function filterItemProps(props) {
      // console.log('filterItemProps', props)
      return ZY.lodash.pick(props, ['field', 'comments'])
    }

    function onPlumbUpdate(e) {
      // let { model, key, newVal, config } = e
      // let v = layoutRef.getToolsData()
      // // console.log(ret)
      // state.value = JSON5.stringify(v)
    }

    function onPlumbDelDep() {
      // let v = layoutRef.getToolsData()
      // // console.log(ret)
      // state.value = JSON5.stringify(v)
    }

    function handleList1() {
      if (widgetConfig2.dragLib === 'base') {
        return getHtmlXmlData().concat(getMiniAppXmlData())
      }
      if (widgetConfig2.dragLib === 'none') {
        return [

        ]
      }
      return getXmlData()
    }

    async  function importFun() {
      let str = await ZY2.fileOpenJSON5()
      if (str) {
        let obj = ZY.JSON5.parse(str)
        // console.log(obj, cachedPlumbContext)
        await importData(cachedPlumbContext, obj)
        await ZY.sleep(1000)
        state.value = str
      }
    }

    function handleClick() {
      alert('handleClick')
    }

    async function exportFun() {
      let v = layoutRef.getToolsData()
      let ret = JSON5.stringify(v)
      let inputTplName = await getApp().confirmMessageBox({
        label: '文件名',
        options: {
          showCancelButton: false
        }
      })

      await ZY_EXT.saveJSONFile({
        data: ret, fileName: inputTplName, prefix: 'slots__',
      })
    }

    function cusHandleDep(dep) {
      console.log('cusHandleDep', dep)
    }

    let plumbOptions = {
      top: [],
      initConfig(config) {
        console.log('initConfig', config)
        return config
      }
    }

    function onPlumbEvents({name, ctx, data} = {}) {
      // console.log('name, ctx, data', name, ctx, data)
      if (name === 'connection') {
        // let ret = getValue(ctx)
        // console.log(ret)
      }
    }

    async function onClickOutside(e) {
      // console.log('onClickOutside', e)
      await  save()
    }

    onBeforeUnmount(() => {
      if (layoutRef) {
        layoutRef.clearLayoutStorage()
      }
    })

    return {
      state,
      getXML,
      plumbOptions,
      openDialog,
      beforeInsert,
      onPlumbInited,
      onEleDragChange,
      cusHandleDep,
      filterItemProps,
      onClickOutside,
      onClosed,
      onSaveLayout,
      importFun,
      exportFun,
      storePrefix,
      save,
      setLayoutRef,
      handleClick,
      handleList1,
      onPlumbUpdate,
      onPlumbEvents,
      getXMLDisplay,
      onPlumbDelDep,
      widgetConfig: widgetConfig2,
      methods,
      listeners,
    }
  },
}
</script>

